照理講,我們應該先了解『神經網路』(Neural Network)概念,再談如何寫程式,但是,概念介紹內容有點硬,為了提高學習興趣,避免一開始就搞一堆數學公式,造成讀者跑光光,所以,還是柿子挑軟的吃,先從簡單的開始,與 Neural Network 先培養感情,如果您是條硬漢,可以等看完下一篇後,再回頭看這一篇。
我們就先來寫一支程式,目標是『辨識阿拉伯數字(0~9)』。
首先是選擇開發環境,一般而言,Python 及 R 都有很好的支援及大量的函數庫(Library/Toolbox),而 Python 的框架較易於系統整合(Web、Mobile),因此我選擇 Python,但支援 Python 的 Neural Network 框架(Framework)也很多,參見下圖,要選擇哪一個呢?
圖. Machine Learning 框架(Framework)GitHub評比,資料來源:【AI關鍵技術】三大熱門深度學習框架新進展。
其中,TensorFlow 網路聲量最高,因此,我們採用它作為程式開發的基礎,Keras 則是支援TensorFlow的更高階函數庫(Meta Framework),可以用很簡潔的程式碼完成一個 Neural Network 模型,非常適合入門學習,因此我們就從 Keras 開始學起。
首先我們要建構開發環境,筆者以 Windows 環境為例,依序安裝以下軟體:
就是這麼簡單,當然,為了加速運算,你也可以安裝支援GPU版本的Tensorflow,NVidia支援CUDA的顯示卡請參考這裡 ,相關安裝程序請參考tensorflow官網,如果要在 Linux 環境開發也行,安裝內容不變, 請參考這裡。
以我的電腦為例,配備如下圖,GPU顯示卡為NVIDIA GeForce GTX 750(1GB memory),實際安裝 Tensorflow GPU 版本的程序如下:
實際測試簡單的程式,確實快很多,但是記憶體太小,遇到複雜的程式,例如後續的CNN程式,需要儲存大量矩陣時,就GG了,所以,奉勸各位,要學 Neural Network,還是要花錢買張新一點的顯示卡,才能省去執行時去泡茶、喝咖啡的時間。
如果一切順利完成,就可以開始寫程式了。等一下,那 IDE 呢? 你可以用記事本、NodePad++、或者PyCharm,我則是使用 VS 2017 Community 版本,它也是一個很不錯的選擇喔,可以像 C# 一樣的除錯。另外,使用 Jupyter Notebook,可以讓你像作筆記一樣的寫程式,總之,戲法人人會變,端看你熟悉甚麼樣的環境與工具。
撰寫 Keras 程式,我們需要了解簡單的 Python 語法,建議快速瀏覽『Introducing Python』這本書的第二~四章就夠了,它不只有中文版,也有免費的PDF電子書喔。
以下範例主要是利用 MNIST 資料集的訓練資料,建立單一隱藏層(Hidden Layer)的 Neural Network 模型,以預測實際影像是哪一個阿拉伯數字,如下圖:
圖. 阿拉伯數字(0~9)辨識的流程
流程步驟如下:
程式很簡單,先看註解(#開頭),即可了解整個流程:
# 導入函式庫
import numpy as np
from keras.models import Sequential
from keras.datasets import mnist
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.utils import np_utils # 用來後續將 label 標籤轉為 one-hot-encoding
from matplotlib import pyplot as plt
# 載入 MNIST 資料庫的訓練資料,並自動分為『訓練組』及『測試組』
(X_train, y_train), (X_test, y_test) = mnist.load_data()
# 建立簡單的線性執行的模型
model = Sequential()
# Add Input layer, 隱藏層(hidden layer) 有 256個輸出變數
model.add(Dense(units=256, input_dim=784, kernel_initializer='normal', activation='relu'))
# Add output layer
model.add(Dense(units=10, kernel_initializer='normal', activation='softmax'))
# 編譯: 選擇損失函數、優化方法及成效衡量方式
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
# 將 training 的 label 進行 one-hot encoding,例如數字 7 經過 One-hot encoding 轉換後是 0000001000,即第7個值為 1
y_TrainOneHot = np_utils.to_categorical(y_train)
y_TestOneHot = np_utils.to_categorical(y_test)
# 將 training 的 input 資料轉為2維
X_train_2D = X_train.reshape(60000, 28*28).astype('float32')
X_test_2D = X_test.reshape(10000, 28*28).astype('float32')
x_Train_norm = X_train_2D/255
x_Test_norm = X_test_2D/255
# 進行訓練, 訓練過程會存在 train_history 變數中
train_history = model.fit(x=x_Train_norm, y=y_TrainOneHot, validation_split=0.2, epochs=10, batch_size=800, verbose=2)
# 顯示訓練成果(分數)
scores = model.evaluate(x_Test_norm, y_TestOneHot)
print()
print("\t[Info] Accuracy of testing data = {:2.1f}%".format(scores[1]*100.0))
# 預測(prediction)
X = x_Test_norm[0:10,:]
predictions = np.argmax(model.predict(X), axis=-1)
# get prediction result
print(predictions)
執行方法很簡單,在DOS執行Python,接著將以上程式一段段貼上即可,我們就可以觀察每段程式的用途,要看變數內容,只要輸入變數名稱即可,全部執行完,可以看到準確率有 85%,夠神奇吧,畢竟我們只寫了10多行的程式(不含註解)。
要確認預測是否正確,可以再貼上下列程式,查看影像:
# 顯示 第一筆訓練資料的圖形,確認是否正確
plt.imshow(X_test[0])
plt.show()
如果我們要看優化的過程,可以輸入以下程式,結果如下圖:
plt.plot(train_history.history['loss'])
plt.plot(train_history.history['val_loss'])
plt.title('Train History')
plt.ylabel('loss')
plt.xlabel('Epoch')
plt.legend(['loss', 'val_loss'], loc='upper left')
plt.show()
圖. 優化過程的損失函數(Loss)的變化
進行到這裡,我們已經跨出了一小步,後續我們接著抽絲剝繭,好好研究它為什麼可以這麼厲害。
相關程式請至這裡 下載,本範例為0.py。
感謝您用簡單、程式人員看的懂的方式,指導入門!!
不過,最近考慮打掉重練,從基礎紮根,畢竟學了6年統計,不用可惜。
謝謝您的鼓勵。
老師您好,我是您艾鍗生醫AI班近期的學生,上完老師的課,意猶未盡,有聽到老師說可以來挑戰IT邦鐵人賽,我也來參戰了,不過要介紹的東西是全端的框架,希望可以達到跟老師一樣的文章品質。
讚喔,加油 !!
2.安裝完 CUDA Toolkit 後,再下載 cuDNN v6.x ,並將壓縮檔解開,複製到 CUDA Toolkit 8.0 安裝目錄下同名子目錄下。
現在不用那麼麻煩了,只要用下列指令安裝即可。
pip uninstall tensorflow
conda install tensorflow
查詢過網上相關文章也不明所以
煩請版主為小弟解惑
現在不用那麼麻煩了,只要用下列指令安裝即可。
pip uninstall tensorflow
conda install tensorflow
求助
TypeError Traceback (most recent call last)
in ()
4 model.add(Dense(units=256, input_dim=784, kernel_initializer='normal', activation='relu'))
5 # Add output layer
----> 6 model.add(Dense(units=10, input_dim=784,kernel_initializer='normal', activation='softmax'))
~\Anaconda3\lib\site-packages\keras\engine\sequential.py in add(self, layer)
179 self.inputs = network.get_source_inputs(self.outputs[0])
180 elif self.outputs:
--> 181 output_tensor = layer(self.outputs[0])
182 if isinstance(output_tensor, list):
183 raise TypeError('All layers in a Sequential model '
~\Anaconda3\lib\site-packages\keras\engine\base_layer.py in call(self, inputs, **kwargs)
455 # Actually call the layer,
456 # collecting output(s), mask(s), and shape(s).
--> 457 output = self.call(inputs, **kwargs)
458 output_mask = self.compute_mask(inputs, previous_mask)
459
~\Anaconda3\lib\site-packages\keras\layers\core.py in call(self, inputs)
881 output = K.bias_add(output, self.bias, data_format='channels_last')
882 if self.activation is not None:
--> 883 output = self.activation(output)
884 return output
885
~\Anaconda3\lib\site-packages\keras\activations.py in softmax(x, axis)
29 raise ValueError('Cannot apply softmax to a tensor that is 1D')
30 elif ndim == 2:
---> 31 return K.softmax(x)
32 elif ndim > 2:
33 e = K.exp(x - K.max(x, axis=axis, keepdims=True))
~\Anaconda3\lib\site-packages\keras\backend\tensorflow_backend.py in softmax(x, axis)
3229 A tensor.
3230 """
-> 3231 return tf.nn.softmax(x, axis=axis)
3232
3233
TypeError: softmax() got an unexpected keyword argument 'axis'
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
y_TrainOneHot = np_utils.to_categorical(y_train)
y_TestOneHot = np_utils.to_categorical(y_test)
X_train_2D = X_train.reshape(60000, 2828).astype('float32')
X_test_2D = X_test.reshape(10000, 2828).astype('float32')
x_Train_norm = X_train_2D/255
x_Test_norm = X_test_2D/255
ValueError Traceback (most recent call last)
in ()
1 # 進行訓練, 訓練過程會存在 train_history 變數中
----> 2 train_history = model.fit(x=x_Train_norm, y=y_TrainOneHot, validation_split=0.2, epochs=10, batch_size=800, verbose=2)
~\Anaconda3\lib\site-packages\keras\engine\training.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, **kwargs)
950 sample_weight=sample_weight,
951 class_weight=class_weight,
--> 952 batch_size=batch_size)
953 # Prepare validation data.
954 do_validation = False
~\Anaconda3\lib\site-packages\keras\engine\training.py in _standardize_user_data(self, x, y, sample_weight, class_weight, check_array_lengths, batch_size)
787 feed_output_shapes,
788 check_batch_axis=False, # Don't enforce the batch size.
--> 789 exception_prefix='target')
790
791 # Generate sample-wise weight values given the sample_weight
and
~\Anaconda3\lib\site-packages\keras\engine\training_utils.py in standardize_input_data(data, names, shapes, check_batch_axis, exception_prefix)
136 ': expected ' + names[i] + ' to have shape ' +
137 str(shape) + ' but got array with shape ' +
--> 138 str(data_shape))
139 return data
140
ValueError: Error when checking target: expected dense_13 to have shape (256,) but got array with shape (10,)
TypeError Traceback (most recent call last)
in ()
4 model.add(Dense(units=256, input_dim=784, kernel_initializer='normal', activation='relu'))
5 # Add output layer
----> 6 model.add(Dense(units=10, input_dim=784,kernel_initializer='normal', activation='softmax'))
~\Anaconda3\lib\site-packages\keras\engine\sequential.py in add(self, layer)
179 self.inputs = network.get_source_inputs(self.outputs[0])
180 elif self.outputs:
--> 181 output_tensor = layer(self.outputs[0])
182 if isinstance(output_tensor, list):
183 raise TypeError('All layers in a Sequential model '
~\Anaconda3\lib\site-packages\keras\engine\base_layer.py in call(self, inputs, **kwargs)
455 # Actually call the layer,
456 # collecting output(s), mask(s), and shape(s).
--> 457 output = self.call(inputs, **kwargs)
458 output_mask = self.compute_mask(inputs, previous_mask)
459
~\Anaconda3\lib\site-packages\keras\layers\core.py in call(self, inputs)
881 output = K.bias_add(output, self.bias, data_format='channels_last')
882 if self.activation is not None:
--> 883 output = self.activation(output)
884 return output
885
~\Anaconda3\lib\site-packages\keras\activations.py in softmax(x, axis)
29 raise ValueError('Cannot apply softmax to a tensor that is 1D')
30 elif ndim == 2:
---> 31 return K.softmax(x)
32 elif ndim > 2:
33 e = K.exp(x - K.max(x, axis=axis, keepdims=True))
~\Anaconda3\lib\site-packages\keras\backend\tensorflow_backend.py in softmax(x, axis)
3229 A tensor.
3230 """
-> 3231 return tf.nn.softmax(x, axis=axis)
3232
3233
TypeError: softmax() got an unexpected keyword argument 'axis'
TypeError Traceback (most recent call last)
in ()
4 model.add(Dense(units=256, input_dim=784, kernel_initializer='normal', activation='relu'))
5 # Add output layer
----> 6 model.add(Dense(units=10, kernel_initializer='normal', activation='softmax'))
~\Anaconda3\lib\site-packages\keras\engine\sequential.py in add(self, layer)
179 self.inputs = network.get_source_inputs(self.outputs[0])
180 elif self.outputs:
--> 181 output_tensor = layer(self.outputs[0])
182 if isinstance(output_tensor, list):
183 raise TypeError('All layers in a Sequential model '
~\Anaconda3\lib\site-packages\keras\engine\base_layer.py in call(self, inputs, **kwargs)
455 # Actually call the layer,
456 # collecting output(s), mask(s), and shape(s).
--> 457 output = self.call(inputs, **kwargs)
458 output_mask = self.compute_mask(inputs, previous_mask)
459
~\Anaconda3\lib\site-packages\keras\layers\core.py in call(self, inputs)
881 output = K.bias_add(output, self.bias, data_format='channels_last')
882 if self.activation is not None:
--> 883 output = self.activation(output)
884 return output
885
~\Anaconda3\lib\site-packages\keras\activations.py in softmax(x, axis)
29 raise ValueError('Cannot apply softmax to a tensor that is 1D')
30 elif ndim == 2:
---> 31 return K.softmax(x)
32 elif ndim > 2:
33 e = K.exp(x - K.max(x, axis=axis, keepdims=True))
~\Anaconda3\lib\site-packages\keras\backend\tensorflow_backend.py in softmax(x, axis)
3229 A tensor.
3230 """
-> 3231 return tf.nn.softmax(x, axis=axis)
3232
3233
TypeError: softmax() got an unexpected keyword argument 'axis'
版主您好:
我是個python和keras新手,拜讀您的文章,實測了0.py程式,卻出現了下列訊息
AttributeError: module 'h5py' has no attribute 'File'
求助於版主,謝謝!
在我的PC上測試並無問題,可以參考下列網址測試看看:
https://blog.csdn.net/wangdong2017/article/details/82883044
留言前有試過這個方法,但是錯誤訊息仍然出現。
我把spyder關掉後,重新執行已經OK, 謝謝版主。
請問一下 ,文中「60000資料」怎麼取得?
mnist.load_data() 會取得訓練資料 60000 筆。
謝謝
predictions = model.predict_classes(X)
改為
predictions = (model.predict(X) > 0.5).astype("int32")
model.predict_classes(X) 目前TF已淘汰。
多分類應改為:
np.argmax(model.predict(X), axis=-1)
文章已修正,謝謝。
你好,
我是程式新手,想請問
當我按步完成開發環境建置後再寫程式時出現問題
import numpy as np
Traceback (most recent call last):
File "", line 1, in
ModuleNotFoundError: No module named 'numpy'
請問numpy資料在哪裡可以取得?要放在電腦中哪裡?
需安裝numpy 套件:
pip install numpy
一般會安裝Anaconda, 它會安裝常用的套件包括numpy.
了解,問題已解決
請問建議安裝的anaconda版本為何?
我發現最新版的anaconda跟文章的語法會有不相容的問題.
安裝最新版的anaconda應該可以,出現的問題是?
我是用anaconda 3, 2021-5版本.
0.py: Sequential.predict_classes()
cnn.py: keras.utils.to_categorical()
這兩個function會無法呼叫
除非改成
Sequential.predict()
keras.utils.np_utils.to_categorical()
另外很奇怪的是, cnn.py訓練完之後的正確率只有85%
且跳出以下訊息,
File "C:\workspace\skygoodjob\Python\MyNeuralNetwork-master\cnn.py", line 93, in
pd.crosstab(y_test_org, predictions, rownames=['實際值'], colnames=['預測值'])
File "C:\Users\asus\anaconda3\lib\site-packages\pandas\core\reshape\pivot.py", line 598, in crosstab
df = DataFrame(data, index=common_idx)
File "C:\Users\asus\anaconda3\lib\site-packages\pandas\core\frame.py", line 529, in init
mgr = init_dict(data, index, columns, dtype=dtype)
File "C:\Users\asus\anaconda3\lib\site-packages\pandas\core\internals\construction.py", line 287, in init_dict
return arrays_to_mgr(arrays, data_names, index, columns, dtype=dtype)
File "C:\Users\asus\anaconda3\lib\site-packages\pandas\core\internals\construction.py", line 85, in arrays_to_mgr
arrays = _homogenize(arrays, index, dtype)
File "C:\Users\asus\anaconda3\lib\site-packages\pandas\core\internals\construction.py", line 355, in _homogenize
val = sanitize_array(
File "C:\Users\asus\anaconda3\lib\site-packages\pandas\core\construction.py", line 529, in sanitize_array
raise ValueError("Data must be 1-dimensional")
ValueError: Data must be 1-dimensional
跟Anaconda無關,與TensorFlow相關。
np.argmax(model.predict(test_data), axis=-1)
TensorFlow 規格還在變動中,常有一些函數改變命名空間或廢掉。
老師您好,本學生剛入門程式語言(非本科系),最近在撰寫類神經網路,剛好看到您的這篇實用的教學,本學生參考您的程式碼有做一些修改,想請教您下列問題。
1.本學生目前處理的資料是時間序列的data,共有580筆,input節點10個,隱藏層2層各層11個神經元,output節點1個,想請教若更改我目前的狀況,引用您的程式碼是否這樣正確,再請您指教。另外激活函數使用的leaky relu。
2.本學生想用keras撰寫,所以開頭必須導入(import) keras一些套件,想請問這樣是否有問題?是否有正式導入keras。至於導入資料集,這樣撰寫是否有成功導入到類神經網路,或者有其它指令可以導入資料。以下我這個寫法是必須import pandas就是了。
4.另外想提問一個基礎問題,若我往後想要安裝套件,在主機上在安裝,是否只要開起CMD開頭打pip,是anaconda的話就只要conda開頭即可。
謝謝老師您的這篇文章,對我非常有幫助!
謝謝老師您的指導,本學生獲益良多!